package com.spzx.channel.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.spzx.channel.domain.ItemVo;
import com.spzx.channel.service.IItemService;
import com.spzx.common.core.constant.SecurityConstants;
import com.spzx.common.core.domain.R;
import com.spzx.common.core.exception.ServiceException;
import com.spzx.product.api.RemoteProductService;
import com.spzx.product.domain.Product;
import com.spzx.product.domain.ProductDetails;
import com.spzx.product.domain.ProductSku;
import com.spzx.product.domain.SkuPrice;
import com.spzx.product.domain.vo.SkuStockVo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBloomFilter;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;

import java.time.Instant;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * Package: com.spzx.channel.service.impl
 *
 * @author xiongkunYang
 * @description:
 * @since 2025/6/3 20:09
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class IItemServiceImpl implements IItemService {

    private final RemoteProductService remoteProductService;
    private final RedissonClient redissonClient;
    private final ThreadPoolExecutor threadPoolExecutor;

    @Override
    public ItemVo item(Long skuId) {

        //远程调用商品微服务接口之前 提前知道用户访问商品 skuId 是否存在与布隆过滤器
        RBloomFilter<Object> bloomFilter = redissonClient.getBloomFilter("sku:bloom:filter");
        if (!bloomFilter.contains(skuId)) {
            //查询数据不存在直接返回空对象
            throw new ServiceException("用户查询商品sku不存在");
        }

        long start = Instant.now().toEpochMilli();
        ItemVo itemVo = new ItemVo();
        // @Schema(description = "商品sku信息")private ProductSku productSku;
        CompletableFuture<Long> productSkuFuture = CompletableFuture.supplyAsync(() -> {
            R<ProductSku> productSkuResult = this.remoteProductService.getProductSku(skuId, SecurityConstants.INNER);
            if (R.FAIL == productSkuResult.getCode()) {
                throw new ServiceException(productSkuResult.getMsg());
            }
            ProductSku productSku = productSkuResult.getData();
            itemVo.setProductSku(productSku);
            return productSku.getProductId();
        }, threadPoolExecutor);

        // @Schema(description = "商品信息")private Product product;
        CompletableFuture<Void> productFuture = productSkuFuture.thenAcceptAsync(productId -> {
            R<Product> productResult = this.remoteProductService.getProduct(productId, SecurityConstants.INNER);
            if (R.FAIL == productResult.getCode()) {
                throw new ServiceException(productResult.getMsg());
            }
            Product product = productResult.getData();
            itemVo.setProduct(product);
            // @Schema(description = "商品轮播图列表")private List<String> sliderUrlList;
            List<String> sliderUrlList = Arrays.asList(product.getSliderUrls().split(","));
            itemVo.setSliderUrlList(sliderUrlList);
            // @Schema(description = "商品规格信息")private JSONArray specValueList;
            JSONArray specValueList = JSON.parseArray(product.getSpecValue());
            itemVo.setSpecValueList(specValueList);
        }, threadPoolExecutor);

        // @Schema(description = "商品详情图片列表")private List<String> detailsimagesUrlList;
        CompletableFuture<Void> productDetailsFuture = productSkuFuture.thenAcceptAsync(productId -> {
            R<ProductDetails> productDetailsResult = this.remoteProductService.getProductDetails(productId, SecurityConstants.INNER);
            if (R.FAIL == productDetailsResult.getCode()) {
                throw new ServiceException(productDetailsResult.getMsg());
            }
            ProductDetails productDetails = productDetailsResult.getData();
            itemVo.setDetailsimagesUrlList(Arrays.asList(productDetails.getImageUrls().split(",")));
        }, threadPoolExecutor);

        // @Schema(description = "商品规格对应商品skuId信息")private Map<String,Long> skuSpecValueMap;
        CompletableFuture<Void> skuSpecValueMapFuture = productSkuFuture.thenAcceptAsync(productId -> {
            R<Map<String, Long>> skuSpecValueResult = this.remoteProductService.getSkuSpecValue(productId, SecurityConstants.INNER);
            if (R.FAIL == skuSpecValueResult.getCode()) {
                throw new ServiceException(skuSpecValueResult.getMsg());
            }
            itemVo.setSkuSpecValueMap(skuSpecValueResult.getData());
        }, threadPoolExecutor);

        // @Schema(description = "最新价格信息")private SkuPrice skuPrice;
        CompletableFuture<Void> skuPriceFuture = CompletableFuture.runAsync(() -> {
            R<SkuPrice> skuPriceResult = this.remoteProductService.getSkuPrice(skuId, SecurityConstants.INNER);
            if (R.FAIL == skuPriceResult.getCode()) {
                throw new ServiceException(skuPriceResult.getMsg());
            }
            itemVo.setSkuPrice(skuPriceResult.getData());
        }, threadPoolExecutor);


        // @Schema(description = "商品库存信息")private SkuStockVo skuStockVo;
        CompletableFuture<Void> skuStockVoFuture = CompletableFuture.runAsync(() -> {
            R<SkuStockVo> skuStockVoResult = this.remoteProductService.getSkuStock(skuId, SecurityConstants.INNER);
            if (R.FAIL == skuStockVoResult.getCode()) {
                throw new ServiceException(skuStockVoResult.getMsg());
            }
            itemVo.setSkuStockVo(skuStockVoResult.getData());
        }, threadPoolExecutor);


        CompletableFuture.allOf(
                productSkuFuture,
                productFuture,
                productDetailsFuture,
                skuSpecValueMapFuture,
                skuPriceFuture,
                skuStockVoFuture
        ).join();

        System.out.println("用时:" + (Instant.now().toEpochMilli() - start) + "毫秒");
        return itemVo;
    }
}